#include "eventcommand.h"
#include "eventloop.h"
#include <mutex>
#include <queue>
#include <functional>
#include <condition_variable>
#include "public_define.h"
using namespace DcAdr;

#define Thread_LIMIT_SIZE 900

EventCommand::~EventCommand()
{

}
void EventCommand::appendEvent(ThreadType type, const std::function<void(void)> &func)
{
    {
        std::unique_lock<std::mutex> lock(EventLoop::getInstance(type)->m_mutex);
        EventLoop::getInstance(type)->m_queue.push_back(std::move(func));

        if (global_data::g_debugFlag) // 默认不打印线程队列个数，排查线程阻塞
        {
            if ((uint8_t)type == 1)
            {
                if (EventLoop::getInstance(type)->m_queue.size() > 50)
                {
                    Log_Topic("EventCommand threadpool: {}, count: {} ", (int)type, EventLoop::getInstance(type)->m_queue.size());
                }
            }
            else if (EventLoop::getInstance(type)->m_queue.size() > 10)
            {
                Log_Topic("EventCommand threadpool: {}, count: {} ", (int)type, EventLoop::getInstance(type)->m_queue.size());
            }
        }
    }
    EventLoop::getInstance(type)->m_cond.notify_one();
}

// 当线程队列比较空闲的时候再加入线程队列 （目前只用于E_InDataDealThread线程处理接收数据时用到）
void EventCommand::appendEventIfIdle(ThreadType type, const std::function<void(void)> &func)
{
    static uint64_t aa = 0;

    {
        std::unique_lock<std::mutex> lock(EventLoop::getInstance(type)->m_mutex);
        if (EventLoop::getInstance(type)->m_queue.size() >= Thread_LIMIT_SIZE)
        {
            aa++;
            if (aa == Thread_LIMIT_SIZE) // 阈值的几倍就打印
            {
                Log_ERROR("adr_error; threadpool: {}, count: {} recv:{}", (int)type, EventLoop::getInstance(type)->m_queue.size(), aa);
                aa = 0;
            }
        }
        else
        {
            EventLoop::getInstance(type)->m_queue.push_back(std::move(func));

            if (global_data::g_debugFlag) // 默认不打印线程队列个数，排查线程阻塞
            {
                if ((uint8_t)type == 1)
                {
                    if (EventLoop::getInstance(type)->m_queue.size() > 50)
                    {
                        Log_Topic("EventCommand threadpool: {}, count: {} ", (int)type, EventLoop::getInstance(type)->m_queue.size());
                    }
                }
                else if (EventLoop::getInstance(type)->m_queue.size() > 10)
                {
                    Log_Topic("EventCommand threadpool: {}, count: {} ", (int)type, EventLoop::getInstance(type)->m_queue.size());
                }
            }
        }
    }
    EventLoop::getInstance(type)->m_cond.notify_one();
}

void EventCommand::quitLoop(ThreadType type)
{
    auto func = [type]()
    {
        EventLoop::getInstance(type)->m_isRunning = false;
    };
    appendEvent(type, func);
}